//麻将游戏
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;
const int MAXW=75;

int w,h;
char mj[MAXW+2][MAXW+2];
int x1,y1,x2,y2;
char s[MAXW+1];
struct  Cell
{
    int x,y;
    int dep;
};

int dir_offset[4][2]={
    {-1,0},{1,0},{0,-1},{0,1}
};

void search(int x1,int y1,int x2,int y2){
    queue<Cell> qu;
    bool visited[MAXW+2][MAXW+2];
    memset(visited,false,sizeof(visited));
    bool can=false;
    Cell start={x1,y1,0};
    qu.push(start);
    visited[x1][y1]=true;
    while(!qu.empty()){
        Cell cur=qu.front();
        qu.pop();
        for(int d=0;d<4;d++){
            int k=0;
            while(1){
                k++;
                int newx=cur.x+k*dir_offset[d][0];
                int newy=cur.y+k*dir_offset[d][1];
                if ((newx<0)||(newx>w+1)||(newy<0)||(newy>h+1)) break;
                if (mj[newy][newx]=='X') {
                    if (newx==x2&&newy==y2){
                        can=true;
                        cout<<cur.dep+1<<endl;
                        return;
                    }else break;
                }
                if (!visited[newx][newy]){
                    Cell next={newx,newy,cur.dep+1};
                    qu.push(next);
                    visited[newx][newy]=true;
                }
            }
        }
    }
    if (!can) cout<<0<<endl;
}

int main(){
    cin>>w>>h;
    cin.getline(s,256);
    for(int i=1;i<=h;i++){
        cin.getline(s,256);
        for(int j=1;j<=w;j++) mj[i][j]=s[j-1];
    }
    do {
        cin>>x1>>y1>>x2>>y2;
        if (x1!=0) search(x1,y1,x2,y2);
        else break;
    }while (1);
}
    